System.Threading.Tasks var input = File.ReadAllText(Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "..", "day7.txt")).Split(',').Select(int.Parse).ToArray(); bool IntCodeComputer(int[] mem, IEnumerable inputStream, out IList outputStream) { outputStream = new List(); var ptr = 0; var inp = inputStream.GetEnumerator(); (int[] parmModes, int opcode) op; (int[] parmModes, int opcode) readOpCode(int opCode) => (new[] { (opCode / 100) % 10, (opCode / 1000) % 10, (opCode / 10000) % 10 }, opCode % 100); int getParmVal(int mode, int value) => mode == 0 ? mem[value] : value; int getParm(int parm) => getParmVal(op.parmModes[parm - 1], mem[ptr + parm]); while (mem[ptr] != 99) { op = readOpCode(mem[ptr]); switch (op.opcode) { case 1: mem[mem[ptr + 3]] = getParm(1) + getParm(2); ptr += 4; break; case 2: mem[mem[ptr + 3]] = getParm(1) * getParm(2); ptr += 4; break; case 3: if (!inp.MoveNext()) return false; mem[mem[ptr + 1]] = inp.Current; ptr += 2; break; case 4: outputStream.Add(getParm(1)); ptr += 2; break; case 5: ptr = getParm(1) != 0 ? getParm(2) : ptr + 3; break; case 6: ptr = getParm(1) == 0 ? getParm(2) : ptr + 3; break; case 7: mem[mem[ptr + 3]] = getParm(1) < getParm(2) ? 1 : 0; ptr += 4; break; case 8: mem[mem[ptr + 3]] = getParm(1) == getParm(2) ? 1 : 0; ptr += 4; break; } } return true; } IEnumerable> Permutations(IEnumerable list, int length = 0) { if (length == 0) length = list.Count(); if (length == 1) return list.Select(t => new T[] { t }); return Permutations(list, length - 1) .SelectMany(t => list.Where(e => !t.Contains(e)), (t1, t2) => t1.Concat(new T[] { t2 })); } var part1 = Permutations(Enumerable.Range(0, 5)).Max(phases => { var inp = 0; foreach (var phase in phases) { IntCodeComputer(input.ToArray(), new List { phase, inp }, out var output); inp = output.Last(); } return inp; }); part1.Dump(); var part2 = Permutations(Enumerable.Range(5, 5)).Select(o => o.ToList()).Select(phases => { var aIn = new List { phases[0], 0 }; var bIn = new List { phases[1] }; var cIn = new List { phases[2] }; var dIn = new List { phases[3] }; var eIn = new List { phases[4] }; var done = false; IList output = null; while (!done) { IntCodeComputer(input.ToArray(), aIn, out output); bIn.Add(output.Last()); IntCodeComputer(input.ToArray(), bIn, out output); cIn.Add(output.Last()); IntCodeComputer(input.ToArray(), cIn, out output); dIn.Add(output.Last()); IntCodeComputer(input.ToArray(), dIn, out output); eIn.Add(output.Last()); done = IntCodeComputer(input.ToArray(), eIn, out output); aIn.Add(output.Last()); } return output.Last(); }).Max(); part2.Dump();